home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 6 code / TCP / NewsWatcher / NW Source / Source / ic.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-13  |  26.3 KB  |  869 lines  |  [TEXT/MMCC]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     ic.c
  4.     
  5.     This module encapsulates the interface to the Internet Config system.
  6.     
  7.     Copyright © 1994-1995, Northwestern University.
  8.  
  9. ----------------------------------------------------------------------------*/
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13.  
  14. #include "glob.h"
  15. #include "ic.h"
  16. #include "ICTypes.h"
  17. #include "ICAPI.h"
  18. #include "strutil.h"
  19. #include "fileutil.h"
  20. #include "memutil.h"
  21. #include "apputil.h"
  22. #include "prefs.h"
  23.  
  24.  
  25.  
  26. static ICInstance gInst;
  27. static Boolean gICStartOK = false;
  28.  
  29.  
  30.  
  31. /*----------------------------------------------------------------------------
  32.     MyICGetPref
  33.     
  34.     Get a preference from IC. Same parameters as ICGetPref.
  35. ----------------------------------------------------------------------------*/
  36.  
  37. static pascal ICError MyICGetPref (ICInstance inst, ConstStr255Param key, 
  38.     ICAttr *attr, Ptr buf, long *size)
  39. {
  40.     Str255 keyCopy;        /* word-aligned to avoid crashes on 68000 Macs */
  41.     
  42.     CopyPascalString(keyCopy, (StringPtr)key);
  43.     return ICGetPref(inst, keyCopy, attr, buf, size);
  44. }
  45.  
  46.  
  47.  
  48. /*----------------------------------------------------------------------------
  49.     MyICSetPref
  50.     
  51.     Set a preference to IC. Same parameters as ICSetPref.
  52. ----------------------------------------------------------------------------*/
  53.  
  54. static pascal ICError MyICSetPref (ICInstance inst, ConstStr255Param key, 
  55.     ICAttr attr, Ptr buf, long size)
  56. {
  57.     Str255 keyCopy;        /* word-aligned to avoid crashes on 68000 Macs */
  58.     
  59.     CopyPascalString(keyCopy, (StringPtr)key);
  60.     return ICSetPref(inst, keyCopy, attr, buf, size);
  61. }
  62.  
  63.  
  64.  
  65. /*----------------------------------------------------------------------------
  66.     MyICStart 
  67.     
  68.     Start Internet Config.
  69.     
  70.     Entry:    prefsFileLocated = true if we have found a NewsWatcher Prefs file, 
  71.                 in which case the vRefNum and dirID params are valid, 
  72.                 and we tell Internet Config to search the same folder.
  73.             vRefNum = vol ref num of NewsWatcher Prefs file.
  74.             dirID = dir id of NewsWatcher Prefs file.
  75.             
  76.     This function must be called after locating and reading NewsWatcher's 
  77.     prefs file.
  78. ----------------------------------------------------------------------------*/
  79.  
  80. void MyICStart (Boolean prefsFileLocated, short vRefNum, long dirID)
  81. {
  82.     ICError icErr, icErrCountPref;
  83.     ICDirSpecArray    dirSpecArray;
  84.     long count;
  85.     
  86.     if (gICStartOK) return;
  87.     icErr = ICStart(&gInst, kNewsWatcherSignature);
  88.     if (icErr != noErr) return;
  89.     if (prefsFileLocated) {
  90.         dirSpecArray[0].vRefNum = vRefNum;
  91.         dirSpecArray[0].dirID = dirID;
  92.         icErr = ICFindConfigFile(gInst, 1, &dirSpecArray);
  93.     } else {
  94.         icErr = ICFindConfigFile(gInst, 0, nil);
  95.     }
  96.     if (icErr != noErr) return;
  97.     icErr = ICBegin(gInst, icReadOnlyPerm);
  98.     if (icErr != noErr) return;
  99.     icErrCountPref = ICCountPref(gInst, &count);
  100.     icErr = ICEnd(gInst);
  101.     if (icErr != noErr) return;
  102.     gICStartOK = icErrCountPref == noErr && count > 0;
  103. }
  104.  
  105.  
  106.  
  107. /*----------------------------------------------------------------------------
  108.     MyICStop 
  109.     
  110.     Stop Internet Config.
  111. ----------------------------------------------------------------------------*/
  112.  
  113. void MyICStop (void)
  114. {
  115.     if (gICStartOK) ICStop(gInst);
  116.     gInst = nil;
  117.     gICStartOK = false;
  118. }
  119.  
  120.  
  121.  
  122. /*----------------------------------------------------------------------------
  123.     ReadCStringFromPString 
  124.     
  125.     Read a C string shared pref from a P string IC pref.
  126.     
  127.     Entry:    maxSize = max size of theString.
  128.             key = IC keyword.
  129.             
  130.     Exit:    theString = pref string as read from IC.
  131. ----------------------------------------------------------------------------*/
  132.  
  133. static void ReadCStringFromPString (char *theString, long maxSize, 
  134.     ConstStr255Param key)
  135. {
  136.     CStr255 str;
  137.     ICError icErr;
  138.     ICAttr attr;
  139.     
  140.     icErr = MyICGetPref(gInst, key, &attr, (Ptr)str, &maxSize);
  141.     if (icErr != noErr) return;
  142.     p2cstr((StringPtr)str);
  143.     if (EqualString(key, kICRealName, true, true)) {
  144.         if (!ValidCString(str, sizeof(gPrefs.fullName), false)) return;
  145.     } else if (EqualString(key, kICOrganization, true, true)) {
  146.         if (!ValidCString(str, sizeof(gPrefs.organization), false)) return;
  147.     } else if (EqualString(key, kICEmail, true, true)) {
  148.         if (!ValidCString(str, sizeof(gPrefs.emailAddress), false)) return;
  149.     }
  150.     strcpy(theString, str);
  151. }
  152.  
  153.  
  154.  
  155. /*----------------------------------------------------------------------------
  156.     ReadPStringFromPString 
  157.     
  158.     Read a P string shared pref from a P string IC pref.
  159.     
  160.     Entry:    maxSize = max size of theString.
  161.             key = IC keyword.
  162.             
  163.     Exit:    theString = pref string as read from IC.
  164. ----------------------------------------------------------------------------*/
  165.  
  166. static void ReadPStringFromPString (StringPtr theString, long maxSize, 
  167.     ConstStr255Param key)
  168. {
  169.     Str255 str;
  170.     ICError icErr;
  171.     ICAttr attr;
  172.     
  173.     icErr = MyICGetPref(gInst, key, &attr, (Ptr)str, &maxSize);
  174.     if (icErr != noErr) return;
  175.     if (EqualString(key, kICNNTPHost, true, true)) {
  176.         if (!ValidPString(str, sizeof(gPrefs.newsServerName), false)) return;
  177.     } else if (EqualString(key, kICSMTPHost, true, true)) {
  178.         if (!ValidPString(str, sizeof(gPrefs.mailServerName), false)) return;
  179.     }    
  180.     CopyPascalString(theString, str);
  181. }
  182.  
  183.  
  184.  
  185. /*----------------------------------------------------------------------------
  186.     ReadCStringFromText 
  187.     
  188.     Read a C string shared pref from a text IC pref.
  189.     
  190.     Entry:    maxSize = max size of theString.
  191.             key = IC keyword.
  192.             
  193.     Exit:    theString = pref string as read from IC.
  194. ----------------------------------------------------------------------------*/
  195.  
  196. static void ReadCStringFromText (char *theString, long maxSize, 
  197.     ConstStr255Param key)
  198. {
  199.     char buf[4096];
  200.     ICError icErr;
  201.     ICAttr attr;
  202.     long size;
  203.     
  204.     size = maxSize - 1;
  205.     icErr = MyICGetPref(gInst, key, &attr, (Ptr)buf, &size);
  206.     if (icErr != noErr) return;
  207.     buf[size] = 0;
  208.     if (EqualString(key, kICSignature, true, true)) {
  209.         if (!ValidCString(buf, sizeof(gPrefs.signature), true)) return;
  210.     }
  211.     BlockMoveData(buf, theString, size+1);
  212. }
  213.  
  214.  
  215.  
  216. /*----------------------------------------------------------------------------
  217.     ReadFolderFromFileSpec 
  218.     
  219.     Read a default folder shared pref from an ICFileSpec IC pref.
  220.     
  221.     Entry:    key = IC keyword.
  222.             
  223.     Exit:    *defaultFolderAlias = handle to default folder alias.
  224. ----------------------------------------------------------------------------*/
  225.  
  226. static void ReadFolderFromFileSpec (AliasHandle *defaultFolderAlias, 
  227.     ConstStr255Param key)
  228. {
  229.     char buf[4096];
  230.     ICError icErr;
  231.     ICAttr attr;
  232.     long size;
  233.     ICFileSpec *p;
  234.     AliasHandle alias;
  235.     OSErr err = noErr;
  236.     
  237.     size = sizeof(buf);
  238.     icErr = MyICGetPref(gInst, key, &attr, (Ptr)buf, &size);
  239.     if (icErr == noErr) {
  240.         p = (ICFileSpec*)buf;
  241.         if (p->alias.aliasSize == 0) {
  242.             err = VolNameAndCreationDateToVRefNum(p->vol_name, p->vol_creation_date,
  243.                 &p->fss.vRefNum);
  244.             if (err != noErr) return;
  245.             err = NewAlias(nil, &p->fss, &alias);
  246.             if (err != noErr) return;
  247.         } else {
  248.             err = MyNewHandle(p->alias.aliasSize, &alias);
  249.             if (err != noErr) return;
  250.             BlockMoveData(&p->alias, *alias, p->alias.aliasSize);
  251.         }
  252.         MyDisposeHandle(*defaultFolderAlias);
  253.         *defaultFolderAlias = alias;
  254.     }
  255. }
  256.  
  257.  
  258.  
  259. /*----------------------------------------------------------------------------
  260.     ReadFontInfo 
  261.     
  262.     Read font info from an ICFontRecord IC pref.
  263.     
  264.     Entry:    key = IC keyword.
  265.             
  266.     Exit:    fontName = font name as read from IC.
  267.             *fontSize = font size as read from IC.
  268. ----------------------------------------------------------------------------*/
  269.  
  270. static void ReadFontInfo (Str255 fontName, short *fontSize, 
  271.     ConstStr255Param key)
  272. {
  273.     ICError icErr;
  274.     ICFontRecord icFontRecord;
  275.     ICAttr attr;
  276.     long size;
  277.  
  278.     size = sizeof(icFontRecord);
  279.     icErr = MyICGetPref(gInst, key, &attr, (Ptr)&icFontRecord, &size);
  280.     if (icErr != noErr) return;
  281.     if (size <= 4 || icFontRecord.size == 0 || *icFontRecord.font == 0) return;
  282.     if (!ValidPString(icFontRecord.font, 255, false)) return;
  283.     CopyPascalString(fontName, icFontRecord.font);
  284.     *fontSize = icFontRecord.size;
  285. }
  286.  
  287.  
  288.  
  289. /*----------------------------------------------------------------------------
  290.     ReadURLHelperInfo 
  291.     
  292.     Read URL Helper info.
  293. ----------------------------------------------------------------------------*/
  294.  
  295. static void ReadURLHelperInfo (void)
  296. {
  297.     ICError icErr;
  298.     Str255 key;
  299.     long i, count;
  300.     short prefixLen, schemeNameLen;
  301.     TURLSchemeName schemeName;
  302.     TURLHelperInfo **h = nil;
  303.     OSErr err = noErr;
  304.     TURLHelperInfo helperInfo;
  305.     TURLHelperInfo *p;
  306.     ICAppSpec icAppSpec;
  307.     ICAttr attr;
  308.     long size, hSize = 0;
  309.     short numHelpers = 0;
  310.     
  311.     err = MyNewHandle(0, &h);
  312.     if (err != noErr) goto exit;
  313.     
  314.     prefixLen = *kICHelper;
  315.     
  316.     icErr = ICCountPref(gInst, &count);
  317.     if (icErr != noErr) goto exit;
  318.     
  319.     for (i = 1; i <= count; i++) {
  320.         icErr = ICGetIndPref(gInst, i, key);
  321.         if (icErr != noErr) goto exit;
  322.         schemeNameLen = *key - prefixLen;
  323.         if (schemeNameLen > 0 && schemeNameLen <= kMaxSchemeNameLen &&
  324.             MyStrNEqual((char*)key+1, (char*)kICHelper+1, prefixLen)) 
  325.         {
  326.             BlockMoveData(key + prefixLen + 1, schemeName, schemeNameLen);
  327.             schemeName[schemeNameLen] = 0;
  328.             if (!MyStrEqual(schemeName, "editor") && !MyStrEqual(schemeName, "mailto") &&
  329.                 !MyStrEqual(schemeName, "nntp") && !MyStrEqual(schemeName, "news"))
  330.             {
  331.                 size = sizeof(icAppSpec);
  332.                 icErr = MyICGetPref(gInst, key, &attr, (Ptr)&icAppSpec, &size);
  333.                 if (icErr != noErr) goto exit;
  334.                 strcpy(helperInfo.schemeName, schemeName);
  335.                 helperInfo.sig = icAppSpec.fCreator;
  336.                 helperInfo.versionNumber = 0;
  337.                 helperInfo.lastMod = 0;
  338.                 for (p = *gPrefs.urlHelpers; *p->schemeName != 0; p++) {
  339.                     if (MyStrEqual(schemeName, p->schemeName)) {
  340.                         if (helperInfo.sig == p->sig) {
  341.                             helperInfo.versionNumber = p->versionNumber;
  342.                             helperInfo.lastMod = p->lastMod;
  343.                         } 
  344.                         break;
  345.                     }
  346.                 }
  347.                 hSize += sizeof(TURLHelperInfo);
  348.                 err = MySetHandleSize(h, hSize);
  349.                 if (err != noErr) goto exit;
  350.                 (*h)[numHelpers] = helperInfo;
  351.                 numHelpers++;
  352.             }
  353.         }
  354.     }
  355.     
  356.     hSize += sizeof(TURLHelperInfo);
  357.     err = MySetHandleSize(h, hSize);
  358.     memset(*h + numHelpers, 0, sizeof(TURLHelperInfo));
  359.     
  360.     MyDisposeHandle(gPrefs.urlHelpers);
  361.     gPrefs.urlHelpers = h;
  362.     
  363.     return;
  364.     
  365. exit:
  366.  
  367.     MyDisposeHandle(h);
  368.     return;
  369. }
  370.  
  371.  
  372.  
  373. /*----------------------------------------------------------------------------
  374.     ReadEditorInfo 
  375.     
  376.     Read text editor info from an ICAppSpec IC pref.
  377.             
  378.     Exit:    *sig = signature of editor applicaton.
  379. ----------------------------------------------------------------------------*/
  380.  
  381. static void ReadEditorInfo (OSType *sig)
  382. {
  383.     ICError icErr;
  384.     ICAppSpec icAppSpec;
  385.     ICAttr attr;
  386.     long size;
  387.     
  388.     size = sizeof(icAppSpec);
  389.     icErr = MyICGetPref(gInst, kICeditorHelper, &attr, (Ptr)&icAppSpec, &size);
  390.     if (icErr == noErr) *sig = icAppSpec.fCreator;
  391. }
  392.  
  393.  
  394.  
  395. /*----------------------------------------------------------------------------
  396.     MyICReadURLHelperPref 
  397.     
  398.     Read a URL helper program Internet Config pref.
  399.     
  400.     Entry:    schemeName = URL scheme name.
  401. ----------------------------------------------------------------------------*/
  402.  
  403. void MyICReadURLHelperPref (TURLSchemeName schemeName)
  404. {
  405.     ICError icErr;
  406.     Str255 key;
  407.     short len;
  408.     ICAppSpec icAppSpec;
  409.     ICAttr attr;
  410.     long size;
  411.     short i;
  412.     TURLHelperInfo *p;
  413.     OSErr err = noErr;
  414.  
  415.     if (!gICStartOK) return;
  416.     
  417.     icErr = ICBegin(gInst, icReadOnlyPerm);
  418.     if (icErr != noErr) return;
  419.     
  420.     CopyPascalString(key, kICHelper);
  421.     len = strlen(schemeName);
  422.     BlockMoveData(schemeName, key + *key + 1, len);
  423.     *key += len;
  424.     
  425.     size = sizeof(icAppSpec);
  426.     icErr = MyICGetPref(gInst, key, &attr, (Ptr)&icAppSpec, &size);
  427.     if (icErr != noErr && icErr != icPrefNotFoundErr) goto exit;
  428.     
  429.     for (i = 0, p = *gPrefs.urlHelpers; *p->schemeName != 0; i++, p++) {
  430.         if (MyStrEqual(schemeName, p->schemeName)) break;
  431.     }
  432.     
  433.     if (icErr == noErr) {
  434.         if (*p->schemeName == 0) {
  435.             /* IC has this scheme, but NW does not. Add the new scheme to the end of
  436.                the gPrefs.urlHelpers array. */
  437.             size = MyGetHandleSize(gPrefs.urlHelpers);
  438.             err = MySetHandleSize(gPrefs.urlHelpers, size + sizeof(TURLHelperInfo));
  439.             if (err != noErr) goto exit;
  440.             p = &(*gPrefs.urlHelpers)[i];
  441.             strcpy(p->schemeName, schemeName);
  442.             p->sig = icAppSpec.fCreator;
  443.             p->versionNumber = 0;
  444.             p->lastMod = 0;
  445.             memset(p+1, 0, sizeof(TURLHelperInfo));
  446.         } else {
  447.             /* Both IC and NW have this scheme. Update the info for this helper in
  448.                the gPrefs.urlHelpers array. */
  449.             if (icAppSpec.fCreator == p->sig) goto exit;
  450.             p->sig = icAppSpec.fCreator;
  451.             p->versionNumber = 0;
  452.             p->lastMod = 0;
  453.         }
  454.     } else {
  455.         if (*p->schemeName == 0) {
  456.             /* IC does not have this scheme, and neither does NW. Just return. */
  457.             goto exit;
  458.         } else {
  459.             /* IC does not have this scheme, but NW does. Delete it from the 
  460.                gPrefs.urlHelpers array. */
  461.             size = MyGetHandleSize(gPrefs.urlHelpers);
  462.             BlockMoveData(
  463.                 *gPrefs.urlHelpers + i + 1,
  464.                 *gPrefs.urlHelpers + i,
  465.                 size - (i+1) * sizeof(TURLHelperInfo));
  466.             MySetHandleSize(gPrefs.urlHelpers, size - sizeof(TURLHelperInfo));
  467.         }
  468.     }
  469.     
  470. exit:
  471.  
  472.     ICEnd(gInst);
  473. }
  474.     
  475.  
  476.  
  477. /*----------------------------------------------------------------------------
  478.     MyICReadSharedPrefs 
  479.     
  480.     Read shared Internet Config prefs.
  481.     
  482.     Entry:    key = IC keyword for shared pref.
  483. ----------------------------------------------------------------------------*/
  484.  
  485. void MyICReadSharedPrefs (ConstStr255Param key)
  486. {
  487.     ICError icErr;
  488.  
  489.     if (!gICStartOK) return;
  490.     
  491.     icErr = ICBegin(gInst, icReadOnlyPerm);
  492.     if (icErr != noErr) return;
  493.     
  494.     if (EqualString(key, kICAllSharedPrefs, true, true)) {
  495.         ReadCStringFromPString(gPrefs.fullName, sizeof(gPrefs.fullName), 
  496.             kICRealName);
  497.         ReadCStringFromPString(gPrefs.organization, sizeof(gPrefs.organization),
  498.             kICOrganization);
  499.         ReadCStringFromPString(gPrefs.quoteString, sizeof(gPrefs.quoteString),
  500.             kICQuotingString);
  501.         ReadCStringFromText(gPrefs.signature, sizeof(gPrefs.signature),
  502.             kICSignature);
  503.         ReadCStringFromPString(gPrefs.emailAddress, sizeof(gPrefs.emailAddress),
  504.             kICEmail);
  505.         ReadPStringFromPString(gPrefs.mailServerName, sizeof(gPrefs.mailServerName),
  506.             kICSMTPHost);
  507.         ReadCStringFromText(gPrefs.extraMailHdrLines, sizeof(gPrefs.extraMailHdrLines),
  508.             kICMailHeaders);
  509.         ReadCStringFromPString(gPrefs.authUsername, sizeof(gPrefs.authUsername),
  510.             kICNewsAuthUsername);
  511.         ReadCStringFromPString(gPrefs.authPassword, sizeof(gPrefs.authPassword),
  512.             kICNewsAuthPassword);
  513.         ReadPStringFromPString(gPrefs.newsServerName, sizeof(gPrefs.newsServerName),
  514.             kICNNTPHost);
  515.         ReadCStringFromText(gPrefs.extraNewsHdrLines, sizeof(gPrefs.extraNewsHdrLines),
  516.             kICNewsHeaders);
  517.         ReadFolderFromFileSpec(&gPrefs.savedBinDefaultFolderAlias, kICDownloadFolder);
  518.         ReadFontInfo(gPrefs.textFont, &gPrefs.textSize, kICScreenFont);
  519.         ReadFontInfo(gPrefs.listFont, &gPrefs.listSize, kICListFont);
  520.         ReadFontInfo(gPrefs.printingFont, &gPrefs.printingSize, kICPrinterFont);
  521.         ReadURLHelperInfo();
  522.         ReadEditorInfo(&gPrefs.savedArtCreator);
  523.     } else if (EqualString(key, kICRealName, true, true)) {
  524.         ReadCStringFromPString(gPrefs.fullName, sizeof(gPrefs.fullName), 
  525.             kICRealName);
  526.     } else if (EqualString(key, kICOrganization, true, true)) {
  527.         ReadCStringFromPString(gPrefs.organization, sizeof(gPrefs.organization),
  528.             kICOrganization);
  529.     } else if (EqualString(key, kICQuotingString, true, true)) {
  530.         ReadCStringFromPString(gPrefs.quoteString, sizeof(gPrefs.quoteString),
  531.             kICQuotingString);
  532.     } else if (EqualString(key, kICSignature, true, true)) {
  533.         ReadCStringFromText(gPrefs.signature, sizeof(gPrefs.signature),
  534.             kICSignature);
  535.     } else if (EqualString(key, kICEmail, true, true)) {
  536.         ReadCStringFromPString(gPrefs.emailAddress, sizeof(gPrefs.emailAddress),
  537.             kICEmail);
  538.     } else if (EqualString(key, kICSMTPHost, true, true)) {
  539.         ReadPStringFromPString(gPrefs.mailServerName, sizeof(gPrefs.mailServerName),
  540.             kICSMTPHost);
  541.     } else if (EqualString(key, kICMailHeaders, true, true)) {
  542.         ReadCStringFromText(gPrefs.extraMailHdrLines, sizeof(gPrefs.extraMailHdrLines),
  543.             kICMailHeaders);
  544.     } else if (EqualString(key, kICNewsAuthUsername, true, true)) {
  545.         ReadCStringFromPString(gPrefs.authUsername, sizeof(gPrefs.authUsername),
  546.             kICNewsAuthUsername);
  547.     } else if (EqualString(key, kICNewsAuthPassword, true, true)) {
  548.         ReadCStringFromPString(gPrefs.authPassword, sizeof(gPrefs.authPassword),
  549.             kICNewsAuthPassword);
  550.     } else if (EqualString(key, kICNNTPHost, true, true)) {
  551.         ReadPStringFromPString(gPrefs.newsServerName, sizeof(gPrefs.newsServerName),
  552.             kICNNTPHost);
  553.     } else if (EqualString(key, kICNewsHeaders, true, true)) {
  554.         ReadCStringFromText(gPrefs.extraNewsHdrLines, sizeof(gPrefs.extraNewsHdrLines),
  555.             kICNewsHeaders);
  556.     } else if (EqualString(key, kICDownloadFolder, true, true)) {
  557.         ReadFolderFromFileSpec(&gPrefs.savedBinDefaultFolderAlias, kICDownloadFolder);
  558.     } else if (EqualString(key, kICScreenFont, true, true)) {
  559.         ReadFontInfo(gPrefs.textFont, &gPrefs.textSize, kICScreenFont);
  560.     } else if (EqualString(key, kICListFont, true, true)) {
  561.         ReadFontInfo(gPrefs.listFont, &gPrefs.listSize, kICListFont);
  562.     } else if (EqualString(key, kICPrinterFont, true, true)) {
  563.         ReadFontInfo(gPrefs.printingFont, &gPrefs.printingSize, kICPrinterFont);
  564.     } else if (EqualString(key, kICeditorHelper, true, true)) {
  565.         ReadEditorInfo(&gPrefs.savedArtCreator);
  566.     }
  567.     
  568.     ICEnd(gInst);
  569. }
  570.  
  571.  
  572.  
  573. /*----------------------------------------------------------------------------
  574.     WriteCStringToPString 
  575.     
  576.     Write a C string shared pref to a P string IC pref.
  577.     
  578.     Entry:    theString = pointer to C string shared pref.
  579.             key = IC keyword.
  580. ----------------------------------------------------------------------------*/
  581.  
  582. static void WriteCStringToPString (char *theString, ConstStr255Param key)
  583. {
  584.     c2pstr(theString);
  585.     MyICSetPref(gInst, key, ICattr_no_change, (Ptr)theString, *theString+1); 
  586.     p2cstr((StringPtr)theString);
  587. }
  588.  
  589.  
  590.  
  591. /*----------------------------------------------------------------------------
  592.     WritePStringToPString 
  593.     
  594.     Write a P string shared pref to a P string IC pref.
  595.     
  596.     Entry:    theString = pointer to P string shared pref.
  597.             key = IC keyword.
  598. ----------------------------------------------------------------------------*/
  599.  
  600. static void WritePStringToPString (StringPtr theString, ConstStr255Param key)
  601. {
  602.     MyICSetPref(gInst, key, ICattr_no_change, (Ptr)theString, *theString+1); 
  603. }
  604.  
  605.  
  606.  
  607. /*----------------------------------------------------------------------------
  608.     WriteCStringToText 
  609.     
  610.     Write a C string shared pref to a text IC pref.
  611.     
  612.     Entry:    theString = pointer to C string shared pref.
  613.             key = IC keyword.
  614. ----------------------------------------------------------------------------*/
  615.  
  616. static void WriteCStringToText (char *theString, ConstStr255Param key)
  617. {
  618.     MyICSetPref(gInst, key, ICattr_no_change, (Ptr)theString, strlen(theString));
  619. }
  620.  
  621.  
  622.  
  623. /*----------------------------------------------------------------------------
  624.     WriteFolderToFileSpec 
  625.     
  626.     Write a default folder shared pref to an ICFileSpec IC pref.
  627.     
  628.     Entry:    defaultFolderAlias = Handle to alias for default folder
  629.             key = IC keyword.
  630. ----------------------------------------------------------------------------*/
  631.  
  632. static void WriteFolderToFileSpec (AliasHandle defaultFolderAlias, 
  633.     ConstStr255Param key)
  634. {
  635.     char buf[4096];
  636.     OSErr err = noErr;
  637.     ICFileSpec *p;
  638.     HParamBlockRec pb;
  639.     Str31 volName;
  640.     long aliasSize, size;
  641.     FSSpec fss;
  642.     Boolean wasChanged;
  643.     
  644.     if (defaultFolderAlias == nil) return;
  645.     err = ResolveAlias(nil, defaultFolderAlias, &fss, &wasChanged); 
  646.     if (err != noErr) return;
  647.     pb.volumeParam.ioNamePtr = volName;
  648.     pb.volumeParam.ioVolIndex = 0;
  649.     pb.volumeParam.ioVRefNum = fss.vRefNum;
  650.     err = PBHGetVInfoSync(&pb);
  651.     p = (ICFileSpec*)buf;
  652.     CopyPascalString(p->vol_name, volName);
  653.     p->vol_creation_date = pb.volumeParam.ioVCrDate;
  654.     p->fss = fss;
  655.     aliasSize = (**defaultFolderAlias).aliasSize;
  656.     size = aliasSize + sizeof(Str31) + sizeof(long) + sizeof(FSSpec);
  657.     if (size > sizeof(buf)) return;
  658.     BlockMoveData(*defaultFolderAlias, &p->alias, aliasSize);
  659.     MyICSetPref(gInst, key, ICattr_no_change, (Ptr)buf, size);
  660. }
  661.  
  662.  
  663.  
  664. /*----------------------------------------------------------------------------
  665.     WriteFontInfo 
  666.     
  667.     Read font info to an ICFontRecord IC pref.
  668.     
  669.     Entry:    fontName = font name.
  670.             fontSize = font size.
  671.             key = IC keyword.
  672. ----------------------------------------------------------------------------*/
  673.  
  674. static void WriteFontInfo (Str255 fontName, short fontSize, 
  675.     ConstStr255Param key)
  676. {
  677.     ICError icErr;
  678.     ICFontRecord icFontRecord;
  679.     ICAttr attr;
  680.     long size;
  681.  
  682.     size = sizeof(icFontRecord);
  683.     icErr = MyICGetPref(gInst, key, &attr, (Ptr)&icFontRecord, &size);
  684.     if (icErr == icPrefNotFoundErr) {
  685.         icFontRecord.face = normal;
  686.     } else if (icErr != noErr) {
  687.         return;
  688.     }
  689.     CopyPascalString(icFontRecord.font, fontName);
  690.     icFontRecord.size = fontSize;
  691.     MyICSetPref(gInst, key, ICattr_no_change, (Ptr)&icFontRecord, sizeof(icFontRecord));
  692. }
  693.  
  694.  
  695.  
  696. /*----------------------------------------------------------------------------
  697.     WriteURLHelperInfo 
  698.     
  699.     Write URL Helper info.
  700. ----------------------------------------------------------------------------*/
  701.  
  702. static void WriteURLHelperInfo (void)
  703. {
  704.     ICError icErr;
  705.     Str255 key;
  706.     long i, count;
  707.     short prefixLen, schemeNameLen;
  708.     TURLSchemeName schemeName;
  709.     TURLHelperInfo *p;
  710.     Str255 **keysToDelete = nil;
  711.     short numKeysToDelete = 0;
  712.     OSErr err = noErr;
  713.     TURLHelperInfo helperInfo;
  714.     ICAppSpec icAppSpec;
  715.     
  716.     err = MyNewHandle(0, &keysToDelete);
  717.     if (err != noErr) goto exit;
  718.     
  719.     prefixLen = *kICHelper;
  720.     
  721.     icErr = ICCountPref(gInst, &count);
  722.     if (icErr != noErr) goto exit;
  723.     
  724.     for (i = 1; i <= count; i++) {
  725.         icErr = ICGetIndPref(gInst, i, key);
  726.         if (icErr != noErr) goto exit;
  727.         schemeNameLen = *key - prefixLen;
  728.         if (schemeNameLen > 0 && schemeNameLen <= kMaxSchemeNameLen && 
  729.             MyStrNEqual((char*)key+1, (char*)kICHelper+1, prefixLen)) 
  730.         {
  731.             BlockMoveData(key + prefixLen + 1, schemeName, schemeNameLen);
  732.             schemeName[schemeNameLen] = 0;
  733.             if (!MyStrEqual(schemeName, "editor") && !MyStrEqual(schemeName, "mailto") &&
  734.                 !MyStrEqual(schemeName, "nntp") && !MyStrEqual(schemeName, "news"))
  735.             {
  736.                 for (p = *gPrefs.urlHelpers; *p->schemeName != 0; p++) {
  737.                     if (MyStrEqual(schemeName, p->schemeName)) break;
  738.                 }
  739.                 if (*p->schemeName == 0) {
  740.                     numKeysToDelete++;
  741.                     err = MySetHandleSize(keysToDelete, numKeysToDelete * sizeof(Str255));
  742.                     if (err != noErr) goto exit;
  743.                     BlockMoveData(key, *keysToDelete + numKeysToDelete - 1, sizeof(Str255));
  744.                 }
  745.             }
  746.         }
  747.     }
  748.     
  749.     for (i = 0; i < numKeysToDelete; i++) {
  750.         BlockMoveData(*keysToDelete + i, key, sizeof(Str255));
  751.         ICDeletePref(gInst, key);
  752.     }
  753.     
  754.     for (i = 0; ; i++) {
  755.         helperInfo = (*gPrefs.urlHelpers)[i];
  756.         if (*helperInfo.schemeName == 0) break;
  757.         CopyPascalString(key, kICHelper);
  758.         schemeNameLen = strlen(helperInfo.schemeName);
  759.         BlockMoveData(helperInfo.schemeName, key + prefixLen + 1, schemeNameLen);
  760.         *key += schemeNameLen;
  761.         icAppSpec.fCreator = helperInfo.sig;
  762.         *icAppSpec.name = 0;
  763.         FindAppNameFromSig(helperInfo.sig, icAppSpec.name);
  764.         MyICSetPref(gInst, key, ICattr_no_change, (Ptr)&icAppSpec, sizeof(icAppSpec));
  765.     }
  766.  
  767. exit:
  768.     
  769.     MyDisposeHandle(keysToDelete);
  770.  
  771. }
  772.  
  773.  
  774.  
  775. /*----------------------------------------------------------------------------
  776.     WriteEditorInfo 
  777.     
  778.     Write Editor info to the "editor" helper ICAppSpec IC pref.
  779.     
  780.     Entry:    sig = editor helper signature.
  781. ----------------------------------------------------------------------------*/
  782.  
  783. static void WriteEditorInfo (OSType sig)
  784. {
  785.     ICAppSpec icAppSpec;
  786.     long size;
  787.     OSErr err = noErr;
  788.     
  789.     icAppSpec.fCreator = sig;
  790.     err = FindAppNameFromSig(sig, icAppSpec.name);
  791.     if (err != noErr) *icAppSpec.name = 0;
  792.     size = sizeof(icAppSpec);
  793.     MyICSetPref(gInst, kICeditorHelper, ICattr_no_change, (Ptr)&icAppSpec, size);
  794. }
  795.  
  796.  
  797.  
  798. /*----------------------------------------------------------------------------
  799.     MyICWriteSharedPrefs 
  800.     
  801.     Write shared Internet Config prefs.
  802.     
  803.     Entry:    key = IC keyword for shared pref.
  804. ----------------------------------------------------------------------------*/
  805.  
  806. void MyICWriteSharedPrefs (ConstStr255Param key)
  807. {
  808.     ICError icErr;
  809.  
  810.     if (!gICStartOK) return;
  811.     
  812.     icErr = ICBegin(gInst, icReadWritePerm);
  813.     if (icErr != noErr) return;
  814.     
  815.     if (EqualString(key, kICAllSharedPrefs, true, true)) {
  816.         WriteCStringToPString(gPrefs.fullName, kICRealName);
  817.         WriteCStringToPString(gPrefs.organization, kICOrganization);
  818.         WriteCStringToPString(gPrefs.quoteString, kICQuotingString);
  819.         WriteCStringToText(gPrefs.signature, kICSignature);
  820.         WriteCStringToPString(gPrefs.emailAddress, kICEmail);
  821.         WritePStringToPString(gPrefs.mailServerName, kICSMTPHost);
  822.         WriteCStringToText(gPrefs.extraMailHdrLines, kICMailHeaders);
  823.         WriteCStringToPString(gPrefs.authUsername, kICNewsAuthUsername);
  824.         WriteCStringToPString(gPrefs.authPassword, kICNewsAuthPassword);
  825.         WritePStringToPString(gPrefs.newsServerName, kICNNTPHost);
  826.         WriteCStringToText(gPrefs.extraNewsHdrLines, kICNewsHeaders);
  827.         WriteFolderToFileSpec(gPrefs.savedBinDefaultFolderAlias, kICDownloadFolder); 
  828.         WriteFontInfo(gPrefs.textFont, gPrefs.textSize, kICScreenFont);
  829.         WriteFontInfo(gPrefs.listFont, gPrefs.listSize, kICListFont);
  830.         WriteFontInfo(gPrefs.printingFont, gPrefs.printingSize, kICPrinterFont);
  831.         WriteURLHelperInfo();
  832.         WriteEditorInfo(gPrefs.savedArtCreator);
  833.     } else if (EqualString(key, kICRealName, true, true)) {
  834.         WriteCStringToPString(gPrefs.fullName, kICRealName);
  835.     } else if (EqualString(key, kICOrganization, true, true)) {
  836.         WriteCStringToPString(gPrefs.organization, kICOrganization);
  837.     } else if (EqualString(key, kICQuotingString, true, true)) {
  838.         WriteCStringToPString(gPrefs.quoteString, kICQuotingString);
  839.     } else if (EqualString(key, kICSignature, true, true)) {
  840.         WriteCStringToText(gPrefs.signature, kICSignature);
  841.     } else if (EqualString(key, kICEmail, true, true)) {
  842.         WriteCStringToPString(gPrefs.emailAddress, kICEmail);
  843.     } else if (EqualString(key, kICSMTPHost, true, true)) {
  844.         WritePStringToPString(gPrefs.mailServerName, kICSMTPHost);
  845.     } else if (EqualString(key, kICMailHeaders, true, true)) {
  846.         WriteCStringToText(gPrefs.extraMailHdrLines, kICMailHeaders);
  847.     } else if (EqualString(key, kICNewsAuthUsername, true, true)) {
  848.         WriteCStringToPString(gPrefs.authUsername, kICNewsAuthUsername);
  849.     } else if (EqualString(key, kICNewsAuthPassword, true, true)) {
  850.         WriteCStringToPString(gPrefs.authPassword, kICNewsAuthPassword);
  851.     } else if (EqualString(key, kICNNTPHost, true, true)) {
  852.         WritePStringToPString(gPrefs.newsServerName, kICNNTPHost);
  853.     } else if (EqualString(key, kICNewsHeaders, true, true)) {
  854.         WriteCStringToText(gPrefs.extraNewsHdrLines, kICNewsHeaders);
  855.     } else if (EqualString(key, kICDownloadFolder, true, true)) {
  856.         WriteFolderToFileSpec(gPrefs.savedBinDefaultFolderAlias, kICDownloadFolder); 
  857.     } else if (EqualString(key, kICScreenFont, true, true)) {
  858.         WriteFontInfo(gPrefs.textFont, gPrefs.textSize, kICScreenFont);
  859.     } else if (EqualString(key, kICListFont, true, true)) {
  860.         WriteFontInfo(gPrefs.listFont, gPrefs.listSize, kICListFont);
  861.     } else if (EqualString(key, kICPrinterFont, true, true)) {
  862.         WriteFontInfo(gPrefs.printingFont, gPrefs.printingSize, kICPrinterFont);
  863.     } else if (EqualString(key, kICeditorHelper, true, true)) {
  864.         WriteEditorInfo(gPrefs.savedArtCreator);
  865.     }
  866.     
  867.     ICEnd(gInst);
  868. }
  869.